﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraPrinting.BarCode;
using Sumen.Library.Classes.Common;
using Sumen.Library.Classes.Connection;
using Sumen.Business.Data;
using Sumen.Model.Model;

namespace Sumen.Business.Presenter.Actor
{
    public class ProductPresenter
    {

        string urlDesImage = ClsConnection.LocationSave;
        public string UrlDesImage
        {
            get { return urlDesImage; }
            set { urlDesImage = value; }
        }
        public ProductPresenter()
        {
            urlDesImage = Path.Combine(urlDesImage, "SanPham");
        }

        public int Update(object pObjectValue, long pId, object pListColor, object pListSize)
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                DbContextTransaction trans = objEntities.Database.BeginTransaction();
                try
                {
                    product productInfo = (product)pObjectValue;

                    product tempProduct = objEntities.products.FirstOrDefault(p => p.Prod_ID == pId);
                    string productIdOld = tempProduct.Prod_Product_ID;
                    string productIdNew = productInfo.Prod_Product_ID;
                    tempProduct.Prod_Product_ID = productInfo.Prod_Product_ID;
                    tempProduct.Prod_CATEGORY_ID = productInfo.Prod_CATEGORY_ID;
                    tempProduct.Prod_PROVIDER_ID = productInfo.Prod_PROVIDER_ID;
                    tempProduct.Prod_Product_Name = productInfo.Prod_Product_Name;
                    tempProduct.Prod_PRODUCT_TYPE_ID = productInfo.Prod_PRODUCT_TYPE_ID;
                    tempProduct.Prod_Org_Price = productInfo.Prod_Org_Price;
                    tempProduct.Prod_Sale_Price = productInfo.Prod_Sale_Price;
                    tempProduct.Prod_Inward_Price = productInfo.Prod_Inward_Price;
                    tempProduct.Prod_Agent_Price = productInfo.Prod_Agent_Price;
                    tempProduct.Prod_Retails_Price = productInfo.Prod_Retails_Price;
                    tempProduct.Prod_Title = productInfo.Prod_Title;
                    tempProduct.Prod_Alias = productInfo.Prod_Alias;
                    tempProduct.Prod_Infotext = productInfo.Prod_Infotext;
                    tempProduct.Prod_Published = productInfo.Prod_Published;
                    tempProduct.Prod_Hit = productInfo.Prod_Hit;
                    tempProduct.Prod_Featured = productInfo.Prod_Featured;
                    tempProduct.Prod_MetaDesc = productInfo.Prod_MetaDesc;
                    tempProduct.Prod_MeteKey = productInfo.Prod_MeteKey;
                    tempProduct.Prod_Actived = productInfo.Prod_Actived;

                    if (productIdNew != productIdOld)
                    {
                        //đổi tên Folder và file hình ở đâyyyyyyy
                        string urlFolderStoreImageOld = Path.Combine(urlDesImage, productIdOld);
                        string urlFolderStoreImageNew = Path.Combine(urlDesImage, productIdNew);
                        DirectoryInfo folderOld = new DirectoryInfo(urlFolderStoreImageOld);
                        if (folderOld.Exists)
                        {
                            FileInfo[] filesOld = folderOld.GetFiles();

                            foreach (var fileInfo in filesOld)
                            {
                                if (!fileInfo.IsReadOnly && !fileInfo.Attributes.HasFlag(FileAttributes.System))
                                {
                                    if (!Directory.Exists(urlFolderStoreImageNew)) Directory.CreateDirectory(urlFolderStoreImageNew);
                                    string destFileName = Path.Combine(urlFolderStoreImageNew, fileInfo.Name.Replace(productIdOld, productIdNew));
                                    fileInfo.MoveTo(destFileName);
                                }
                            }
                            Directory.Delete(urlFolderStoreImageOld);
                            tempProduct.Prod_Image = tempProduct.Prod_Image.Replace(productIdOld, productIdNew);
                            tempProduct.Prod_Images = tempProduct.Prod_Images.Replace(productIdOld, productIdNew);
                        }
                    }

                    string[] valueSize = pListSize.ToString().Replace(" ", "").Split(',');
                    string[] valueColor = pListColor.ToString().Replace(" ", "").Split(',');

                    var listByProduct = (from p in objEntities.product_details where p.Prods_PRODUCT_ID == pId select p).ToList();
                    //add

                    //var queryDelete;
                    foreach (var c in valueColor)
                    {
                        foreach (var s in valueSize)
                        {
                            int cId = Convert.ToInt32(c);
                            int sId = Convert.ToInt32(s);
                            //long proId = _productId;
                            var queryAdd = (from p in listByProduct
                                            where
                                                p.Prods_PRODUCT_DETAILS_COLOR_ID == cId &&
                                                p.Prods_PRODUCT_DETAILS_SIZE_ID == sId
                                            select p).FirstOrDefault();
                            if (queryAdd == null)
                            {
                                product_details newProductDetails = new product_details();
                                newProductDetails.Prods_PRODUCT_DETAILS_COLOR_ID = cId;
                                newProductDetails.Prods_PRODUCT_DETAILS_SIZE_ID = sId;
                                newProductDetails.Prods_PRODUCT_ID = pId;
                                product_size objSize = objEntities.product_size.FirstOrDefault(p => p.Size_ID == sId);
                                product_color objColor = objEntities.product_color.FirstOrDefault(p => p.Color_ID == cId);

                                newProductDetails.Prods_ID = tempProduct.Prod_Product_ID + objSize.Size_Code + objColor.Color_Code;
                                objEntities.product_details.Add(newProductDetails);

                            }
                            product_size objSize1 = objEntities.product_size.FirstOrDefault(p => p.Size_ID == sId);
                            product_color objColor1 = objEntities.product_color.FirstOrDefault(p => p.Color_ID == cId);
                            InitImageQRCode(tempProduct.Prod_Product_ID + objSize1.Size_Code + objColor1.Color_Code, tempProduct.Prod_Product_ID);
                        }
                    }
                    foreach (var item in listByProduct)
                    {
                        var a = (from p in valueColor where p == item.Prods_PRODUCT_DETAILS_COLOR_ID.ToString() select p).Count();
                        var b = (from p in valueSize where p == item.Prods_PRODUCT_DETAILS_SIZE_ID.ToString() select p).Count();
                        if (a == 0 || b == 0)
                        {
                            product_details pro = (from p in objEntities.product_details select p).FirstOrDefault(p1 => p1.Prods_ID == item.Prods_ID);
                            objEntities.product_details.Remove(pro);
                        }
                    }
                    objEntities.SaveChanges();
                    trans.Commit();

                    return 1;
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    ClsMsgBox.LoiChung(ex, false);
                    return 0;
                }
            }
        }

        public List<product_details> Add(object pColorList, object pSizeList, object pProduct)
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                List<product_details> list = new List<product_details>();
                DbContextTransaction trans = objEntities.Database.BeginTransaction();
                try
                {
                    product newPro = (product)pProduct;
                    objEntities.products.Add(newPro);
                    objEntities.SaveChanges();
                    long proID = newPro.Prod_ID;
                    string[] valueSize = pSizeList.ToString().Replace(" ", "").Split(',');
                    string[] valueColor = pColorList.ToString().Replace(" ", "").Split(',');
                    //add color and size
                    foreach (var c in valueColor)
                    {
                        foreach (var s in valueSize)
                        {
                            int cId = Convert.ToInt32(c);
                            int sId = Convert.ToInt32(s);
                            product_details newProductDetails = new product_details();
                            newProductDetails.Prods_PRODUCT_DETAILS_COLOR_ID = cId;
                            newProductDetails.Prods_PRODUCT_DETAILS_SIZE_ID = sId;
                            newProductDetails.Prods_PRODUCT_ID = proID;
                            product_size objSize = objEntities.product_size.FirstOrDefault(p => p.Size_ID == sId);
                            product_color objColor = objEntities.product_color.FirstOrDefault(p => p.Color_ID == cId);

                            newProductDetails.Prods_ID = newPro.Prod_Product_ID + objSize.Size_Code + objColor.Color_Code;
                            objEntities.product_details.Add(newProductDetails);
                            list.Add(newProductDetails);
                            objEntities.SaveChanges();

                            InitImageQRCode(newProductDetails.Prods_ID, newPro.Prod_Product_ID);
                        }
                    }
                    trans.Commit();
                    return list;
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    ClsMsgBox.LoiChung(ex, false);
                    return list;
                }
            }
        }

        public void InitImageQRCode(string pProductDetailsId, string pProductCode)
        {
            BarCodeControl barCodeControl1 = new BarCodeControl();
            barCodeControl1.BorderStyle = BorderStyles.NoBorder;
            barCodeControl1.Font = new Font("Tahoma", 13F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            barCodeControl1.HorizontalTextAlignment = DevExpress.Utils.HorzAlignment.Center;
            QRCodeGenerator qrCodeGenerator1 = new QRCodeGenerator();
            qrCodeGenerator1.Version = QRCodeVersion.Version1;
            barCodeControl1.Symbology = qrCodeGenerator1;
            barCodeControl1.Text = pProductDetailsId;
            barCodeControl1.Module = 10D;
            barCodeControl1.Width = 240;
            barCodeControl1.Height = 250;
            Bitmap bitmap = new Bitmap(barCodeControl1.Width, barCodeControl1.Height);
            barCodeControl1.DrawToBitmap(bitmap, barCodeControl1.ClientRectangle);
            try
            {
                string urlDes = Path.Combine(urlDesImage, pProductCode, "QRCode");
                if (!Directory.Exists(urlDes))
                    Directory.CreateDirectory(urlDes);
                string urlImage = Path.Combine(urlDes, pProductDetailsId + ".png");
                if (File.Exists(urlImage))
                {
                    File.Delete(urlImage);
                }
                bitmap.Save(urlImage, ImageFormat.Png);
            }
            catch
            {
            }
            Code128Generator code128 = new Code128Generator();
            barCodeControl1.Symbology = code128;
            barCodeControl1.AutoModule = true;
            Bitmap bitmap128 = new Bitmap(barCodeControl1.Width, barCodeControl1.Height);
            barCodeControl1.DrawToBitmap(bitmap128, barCodeControl1.ClientRectangle);
            try
            {
                string urlDes = Path.Combine(urlDesImage, pProductCode, "Code128");
                if (!Directory.Exists(urlDes))
                    Directory.CreateDirectory(urlDes);
                string urlImage = Path.Combine(urlDes, pProductDetailsId + ".png");
                bitmap128.Save(urlImage, ImageFormat.Png);
            }
            catch
            {
            }
        }

        /// <summary>
        /// Get new sorted product sort by cat id
        /// </summary>
        /// <param name="pCatCode"></param>
        /// <returns></returns>
        public long GetNewSortedProduct(int pCatId)
        {
            using (sumenEntities obj = new sumenEntities())
            {
                long sorted = (from p in obj.products where p.Prod_CATEGORY_ID == pCatId select p).Max(x => x.Prod_Sorted) ?? 0;
                //pCatCode += sorted.ToString().PadLeft(5, '0');
                return sorted + 1;
            }
        }


        public int Delete(long pObjectValue)
        {
            using (sumenEntities context = new sumenEntities())
            {
                product pro = (from p in context.products select p).FirstOrDefault(p1 => p1.Prod_ID == pObjectValue);
                context.products.Remove(pro);
                return context.SaveChanges();
            }
        }

        public ICollection<object> GetAll()
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                var query = from p in objEntities.products
                            select new
                            {
                                p.Prod_ID,
                                p.Prod_Product_ID,
                                p.Prod_Product_Name,
                                p.Prod_CATEGORY_ID,
                                p.category.Cat_Title,
                                p.Prod_PROVIDER_ID,
                                p.provider.Prov_Name,
                                p.Prod_PRODUCT_TYPE_ID,
                                p.product_type.Prodt_Name,
                                p.Prod_Org_Price,
                                p.Prod_Sale_Price,
                                p.Prod_Discount,
                                p.Prod_Image,
                                p.Prod_Images,
                                p.Prod_Infotext,
                                p.Prod_Alias,
                                p.Prod_Published,
                                p.Prod_MetaDesc,
                                p.Prod_MeteKey,
                                p.Prod_Hit,
                                p.Prod_Featured,
                                p.Prod_Description,
                                p.Prod_Actived
                            };
                return query.ToArray();
            }
        }

        public object GetById(long pId)
        {
            using (sumenEntities obj = new sumenEntities())
            {
                product pro = (from p in obj.products where p.Prod_ID == pId select p).First();
                return pro;
            }
        }

        /// <summary>
        /// Find by category product
        /// </summary>
        /// <param name="pValue"></param>
        /// <returns></returns>
        public ICollection<object> GetByKey(List<object> pValue)
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                Dao dao = new Dao(true);
                var result = dao.GetAll<product>();
                var result1 = (from p in result
                               where (pValue != null) ? pValue.Contains((int)p.Prod_CATEGORY_ID) : p.Prod_CATEGORY_ID != null
                               select p);

                //var query1 = (from p in objEntities.products.AsEnumerable() select p).ToList();
                //var query = from p in query1
                //            //where (cat_id != 0) ? p.Prod_CATEGORY_ID == cat_id : p.Prod_CATEGORY_ID != null
                //            where (pValue != null) ? pValue.Contains((int)p.Prod_CATEGORY_ID) : p.Prod_CATEGORY_ID != null
                //            select new
                //            {
                //                p.Prod_ID,
                //                p.Prod_Product_ID,
                //                p.Prod_Product_Name,
                //                p.Prod_CATEGORY_ID,
                //                p.category.Cat_Title,
                //                p.Prod_PROVIDER_ID,
                //                p.provider.Prov_Name,
                //                p.Prod_PRODUCT_TYPE_ID,
                //                p.product_type.Prodt_Name,
                //                p.Prod_Inward_Price,
                //                p.Prod_Sale_Price,
                //                p.Prod_Retails_Price,
                //                p.Prod_Agent_Price,
                //                p.Prod_Discount,
                //                p.Prod_Image,
                //                p.Prod_Images,
                //                p.Prod_Infotext,
                //                p.Prod_Alias,
                //                p.Prod_Published,
                //                p.Prod_MetaDesc,
                //                p.Prod_MeteKey,
                //                p.Prod_Hit,
                //                p.Prod_Featured,
                //                p.Prod_Description,
                //                p.Prod_Actived,
                //                p.Prod_DateModified,
                //                //Picture = GetPicture(urlDesImage,p.Prod_Product_ID, p.Prod_Image)
                //            };
            //    var abc = query.ToList();
                return result1.ToArray();
            }
        }

        public ICollection<object> GetProductDetailsByKey(List<object> pValue)
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                var query1 = objEntities.product_details;
                var invent = (from p in objEntities.inventories
                              group p by new
                                       {
                                           p.Inv_PRODUCT_DETAILS_ID
                                       } into Grouped
                              select new
                                  {
                                      Grouped.Key.Inv_PRODUCT_DETAILS_ID,
                                      Inv_Quantity = Grouped.Sum(p1 => p1.Inv_Quantity)
                                  });
                var query = from p in query1
                            join i in invent on p.Prods_ID equals i.Inv_PRODUCT_DETAILS_ID into Inners
                            from inner in Inners.DefaultIfEmpty()
                            select new
                            {
                                p.Prods_ID,
                                inner.Inv_Quantity,
                                p.product_color.Color_Name,
                                p.product_size.Size_Name,
                                p.product.Prod_ID,
                                p.product.Prod_Product_ID,
                                p.product.Prod_Product_Name,
                                p.product.Prod_CATEGORY_ID,
                                p.product.category.Cat_Title,
                                p.product.Prod_PROVIDER_ID,
                                p.product.provider.Prov_Name,
                                p.product.Prod_PRODUCT_TYPE_ID,
                                p.product.product_type.Prodt_Name,
                                p.product.Prod_Inward_Price,
                                p.product.Prod_Sale_Price,
                                p.product.Prod_Retails_Price,
                                p.product.Prod_Agent_Price,
                                p.product.Prod_Discount,
                                p.product.Prod_Image,
                                p.product.Prod_Images,
                                p.product.Prod_Published,
                                p.product.Prod_Featured,
                                p.product.Prod_Actived,
                                p.product.Prod_DateModified,
                                //Picture = GetPicture(p.product.Prod_Product_ID, p.product.Prod_Image)
                            };
                var result = from p in query.AsEnumerable()
                             where (pValue != null) ? pValue.Contains((int)p.Prod_CATEGORY_ID) : p.Prod_CATEGORY_ID != null
                             select new
                             {
                                 p.Prods_ID,
                                 p.Inv_Quantity,
                                 p.Color_Name,
                                 p.Size_Name,
                                 p.Prod_ID,
                                 p.Prod_Product_ID,
                                 p.Prod_Product_Name,
                                 p.Prod_CATEGORY_ID,
                                 p.Cat_Title,
                                 p.Prod_PROVIDER_ID,
                                 p.Prov_Name,
                                 p.Prod_PRODUCT_TYPE_ID,
                                 p.Prodt_Name,
                                 p.Prod_Inward_Price,
                                 p.Prod_Sale_Price,
                                 p.Prod_Retails_Price,
                                 p.Prod_Agent_Price,
                                 p.Prod_Discount,
                                 p.Prod_Image,
                                 p.Prod_Images,
                                 p.Prod_Published,
                                 p.Prod_Featured,
                                 p.Prod_Actived,
                                 p.Prod_DateModified,
                                 Picture = GetPicture(urlDesImage, p.Prod_Product_ID, p.Prod_Image)
                             };
                return result.ToArray();
            }
        }

        public byte[] GetPicture(string pUrlDesImage, string pProductID, string pImageName)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                if (string.IsNullOrEmpty(pImageName))
                    return null;
                else
                {
                    try
                    {
                        string urlStoreImage = Path.Combine(pUrlDesImage, pProductID, pImageName);
                        Image img = Image.FromFile(urlStoreImage, false);
                        img.GetThumbnailImage(200, img.Height / (img.Width / 200), null, IntPtr.Zero).Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
                        return ms.ToArray();
                    }
                    catch
                    {
                        return null;
                    }
                }
            }
        }



    }
}
